Saltar a contenido

📘 Clase 04: Tool Calling y Function Calling en Python

  • :material-bookmark: Curso: Curso 3: Creación y Desarrollo de Agentes de IA (CLASE 04)
  • :material-signal-cellular-outline: Nivel: Nivel 3 - Avanzado
  • :material-lightbulb-on: Metáfora Central: «El Cinturón de Herramientas de Batman (Acciones en el Mundo Real)»
  • :material-laptop: Wisrovi Studio (Local): 🚀 Abrir Reto👨‍🏫 Modo Tutor
  • :material-file-pdf-box: Manual PDF Oficial: Descargar clase-04-tool-calling-funciones.pdf

Open In Colab Abrir en Studio Local Ver en GitHub


1. 💡 Fundamentación Teórica y Modelo Mental

Permitir al Agente de IA invocar funciones de código externo para interactuar con APIs y bases de datos: 1. Esquema de Herramienta (Tool Schema): Nombre, descripción y parámetros tipados en JSON Schema. 2. Despacho Dinámico: Enrutar la petición del modelo a la función Python real mediante registry.execute(tool_name, **params). 3. Manejo de Errores en Tools: Retornar mensajes de error descriptivos al LLM para autocorrección.

🌟 Modelo Mental de la Sesión: «El Cinturón de Herramientas de Batman (Acciones en el Mundo Real)»

En esta sesión anclamos el aprendizaje en la metáfora del mundo real para visualizar cómo fluyen las estructuras de datos y el flujo de ejecución en la memoria.


2. 🗺️ Arquitectura de Ejecución y Diagrama de Flujo

flowchart LR
    A["🤖 LLM decide: 'call: sumar(a=10, b=20)'"] --> B["🛠️ ToolRegistry Dispatcher"]
    B --> C["🐍 Ejecución Función Python real"]
    C --> D["📤 Resultado: 30 devuelto al Agente"]
    style A fill:#1e293b,color:#ffffff,stroke:#3b82f6,stroke-width:2px
    style B fill:#d97706,color:#ffffff,stroke:#fbbf24,stroke-width:2px
    style C fill:#0f766e,color:#ffffff,stroke:#2dd4bf,stroke-width:2px
    style D fill:#059669,color:#ffffff,stroke:#34d399,stroke-width:2px

3. 💻 Código de Implementación Práctica

class ToolRegistryDemo:
    def __init__(self):
        self.tools = {}

    def register(self, name, fn):
        self.tools[name] = fn

    def run(self, name, **kwargs):
        return self.tools[name](**kwargs)

reg = ToolRegistryDemo()
reg.register("multiplicar", lambda x, y: x * y)
print("Resultado Tool Call:", reg.run("multiplicar", x=6, y=7))
def consultar_clima(ciudad: str):
    return f"Soleado en {ciudad}, 24°C"

herramientas = {"get_weather": consultar_clima}
print(herramientas["get_weather"]("Madrid"))

4. 🛡️ Buenas Prácticas PEP 8: Antipatrones vs Código Pythonic

⚠️ Cuidado con los Antipatrones

eval(f'{nombre_funcion}({argumentos_crudos})')  # ❌ Vulnerabilidad RCE crítica
HERRAMIENTAS[nombre](**argumentos)  # ✅ Mapeo explícito a funciones seguras

5. 🏋️ Desafío Práctico de la Clase

🎯 Enunciado del Reto

Crea una clase ToolRegistry con los métodos: register(self, name: str, fn: Callable), execute(self, name: str, **kwargs: Any) -> Any (debe lanzar KeyError si la herramienta no se encuentra registrada) y list_tools(self) -> List[str].

⚡ Resolución Híbrida en 1 Clic (Local + Web)

Si tienes ejecutando wisrovi ui en tu terminal local, puedes 🚀 Abrir este Reto directamente en tu Studio Local (127.0.0.1:8501) para escribir tu código con auto-formateo AST, inspeccionar variables en el Heap/Stack y evaluarlo con pruebas en tiempo real.

from typing import Callable, Any, Dict, List

class ToolRegistry:
    def __init__(self):
        self._tools: Dict[str, Callable] = {}

    def register(self, name: str, fn: Callable):
        self._tools[name] = fn

    def execute(self, name: str, **kwargs) -> Any:
        if name not in self._tools:
            raise KeyError(f"Herramienta '{name}' no registrada")
        return self._tools[name](**kwargs)

    def list_tools(self) -> List[str]:
        return list(self._tools.keys())
💡 Pista Socrática 1

💡 Pista 1: Guarda las funciones en un diccionario interno self._tools = {}.

💡 Pista Socrática 2

💡 Pista 2: En execute, verifica if name not in self._tools: raise KeyError(...).

💡 Pista Socrática 3

💡 Pista 3: Invoca la función pasando los argumentos con func = self._tools[name]; return func(**kwargs).

Para resolver este ejercicio en tu entorno: 1. Abre el archivo ejercicios/reto.py de esta clase en Visual Studio Code o utiliza wisrovi ui / wisrovi tutor. 2. Implementa tu solución cumpliendo los requisitos y contratos de tipado. 3. Valida tus resultados ejecutando las pruebas unitarias:

pytest tests/curso_03/test_clase_04_tool_calling_funciones.py


6. 📚 Fuentes y Bibliografía Recomendada